// 第一次已经赋予了默认类型
// let user = 'John';
// 修改了类型之后，这样会报错
// user = 1234;

// 几种数据类型 就是: 符号后面可以跟的值(部分)
// 所以 我们在ts文件中。不管是声明变量还是函数，都记得在后面跟: 做类型限制
// 字符串
let user111: any = "John";
// 类型强制转换
let leng: number = (<string>user111).length;
// as 也可以

// 数组
interface IUser {
  id: number;
  name: string;
}
const list: Array<number> = [1, 2, 3, 4];
const list1: Array<number | string> = [1, 2, 3, 4, "1", 5];
const list11: number[] = [2, 3]; // 声明类型为 数字数组
const list111: any[] = [1, "2", {}]; // 任意元素类型的数组
const userList: Array<IUser> = [{ id: 1, name: "xiafan" }];
// 元组  *

// 属于数组的一种(给index定义类型，更具体), 给每个位置单独声明类型
const list2: [number, string] = [1, "2"];

// 枚举 *

// 数字类型会触发自增行为1, 2, 3, 4或 0, 1, 2, 3。
// 如果没有赋值，那么默认值就是其下标
// 结合了一定语义的对象，可以用在错误码，状态，颜色，方向等。
// enum还具有反查功能
// 通过type 也可以模拟enum(虽然不大合适)
enum Direction {
  Up,
  Down = 3,
  Left,
  Right
}

let left: Direction = Direction.Left;

console.log(left); // 4

console.log(Direction[3] === "Down"); // true

// 任意 - any (基本不会出现……)

let id: any = 1;

id = "1";

let oDiv: HTMLElement | null = document.getElementById("app");
// oDiv.style.color = 'red' // 这里就会直接报错提示了

// undefined null
// 和 ? 差不多的效果,表示这个变量可以没有
let s: undefined | null;
let xxx: undefined = null;
let yyy: number = 3;
yyy = null;
console.log(s);

// 和 ? 差不多的效果,表示这个变量可以没有
let x: undefined | number;

x = 1;

console.log(x);

// void

// 一般用于方法的返回值

function run(): void {
  console.log("run");
}

run();

const add = (a: number, b: number): number => {
  return a + b;
};

console.log(add(3, 2));

// never
// 一般用在函数返回值类型中，表示函数被中断了(未执行完毕)。 与void | undefined不同(这里是执行完了)

function error(message: string): never {
  throw new Error(message);
}

error("err~");

// 断言

let listX: Array<number> = [1, 2, 3];

const len: number = listX.length;

// 想法: 其他类型? 需要在tsconfig中修改target为es6
const map1 = new Map();
const set1 = new Set();
